package xq.gwt.ui.crud;

import java.util.HashMap;
import xq.gwt.mvc.model.CommandModel;
import xq.gwt.mvc.model.EntityModel;
import xq.gwt.mvc.model.ListItem;
import xq.gwt.mvc.model.PersistableEntityModel;
import xq.gwt.mvc.model.PropertyModel;
import xq.gwt.ui.crud.PropertyListItemProvider;
import xq.gwt.ui.rpc.AsyncCallbackAdapter;
import xq.gwt.ui.widgets.command.DefaultCommandProcessor;

public class DefaultPropertyListItemProvider implements PropertyListItemProvider {	
	private HashMap<String,HashMap<String, ListItem[]>> listItemsCache = new HashMap<String, HashMap<String,ListItem[]>>();	
				
	@Override
	public void setListItemsAsync(EntityModel entity, CommandModel callback) {		
		if(listItemsCache.containsKey(entity.getName())){
			setEntityListItems(listItemsCache.get(entity.getName()), entity);
			DefaultCommandProcessor.processCommand(callback);
		} else if (entity.hasRelations()){
			ListItemsReceived listItemsReceived = new ListItemsReceived(entity, callback);
			if(entity instanceof PersistableEntityModel){
				CrudServiceProvider.persistanceService.fetchEntityListItems((PersistableEntityModel)entity, listItemsReceived);
			}
		}
		else {
			DefaultCommandProcessor.processCommand(callback);
		}
	}

	private class ListItemsReceived extends AsyncCallbackAdapter<HashMap<String, ListItem[]>> {
		private EntityModel entity;
		private CommandModel callback;
		
		public ListItemsReceived(EntityModel entity, CommandModel callback){
			this.entity = entity;
			this.callback = callback;
		}
		
		@Override
		public void onFailure(Throwable caught) {
			super.onFailure(caught);
			DefaultCommandProcessor.processCommand(callback);			
		}

		@Override
		public void onSuccess(HashMap<String, ListItem[]> result) {			
			setEntityListItems(result,entity);
			listItemsCache.put(entity.getName(), result);
			DefaultCommandProcessor.processCommand(callback);
			
		}		
	}
	
	private void setEntityListItems(HashMap<String, ListItem[]> result, EntityModel entity){
		if(result == null){
			return;
		}
			
		PropertyModel[] props = entity.getProperties();
		if(props == null){
			return;
		}
		
		for (int i = 0; i < props.length; i++) {
			String propName = props[i].getName();
			if(result.containsKey(propName)){
				props[i].setValueItems(result.get(propName));
			}
		}
		
	}
	
	
}
